/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.persistence;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
import java.util.StringTokenizer;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import br.ufmg.dees.insane.model.femModel.Model;
import br.ufmg.dees.insane.model.femModel.node.Node;
import br.ufmg.dees.insane.solution.EquilibriumPath;
import br.ufmg.dees.insane.solution.Solution;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.writer.TableWriter;

/** A class representing a PersistenceAsTable
 * @author CENOURA!!!
 * 07/11/2005
 */
public class PersistenceAsTable implements Persistence, Observer {
    
    /**
     * Comment for <code>serialVersionUID</code>
     */
    private static final long serialVersionUID = 1L;
    
    /** The Model of this persistence. */
    protected static Model model;
    
    /** The Solution of this persistence. */
    protected static Solution solution;
        
    /** The Object which will be serialized. */
    protected File nodeTable;
    
    /** The Object which will be serialized. */
    protected File elementTable;
    
    /** The text which will be serialized. */
    protected String results="";
    protected String results2="";
    protected String results3="";
    protected String results4="";
    protected String[] s;
    protected String[] s1;
    protected String[] s2;
    protected String[] s3;
    protected String[] s4;
    protected String[] s5;
    
    /** The table writer. */
    protected TableWriter writer;
    
    protected boolean writerBoolean=false;
    
    /** Returns the Model of this application.
    *@return The Model of this application.
    */
    public Model getModel()
    {
        return (model);
    }
    
    /** Sets the Model of this application.
    *@param a The Model of this application.
    */
    public void setModel(Model m)
    {
        model = m;
    }
    
    /** Returns the Solution of this application.
    *@return The Solution of this application.
    */
    public Solution getSolution()
    {
        return (solution);
    }
    
    /** Sets the Solution of this application.
    *@param a The Solution of this application.
    */
    public void setSolution(Solution s)
    {
        solution = s;
    }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.persistence.Persistence#fillInsaneFromFile(java.lang.String)
     */
    public void fillInsaneFromFile(String file) {
        
//      Creating and configuring the SAXParser
        SAXParserFactory parserFac = SAXParserFactory.newInstance();
        parserFac.setValidating(true);
        
        try
        {
            SAXParser parser = parserFac.newSAXParser();
            
            //implementing DefaultHandler
            parser.parse(file, new DefaultHandler()
            {
                StringBuffer content = new StringBuffer();
                
                //All the classes which will be instantiated are declared here

                String string;
                String string1;
                String string2;
                int[] nodesVars;
                int[] MPVars;
                ArrayList<Integer> aux;
                HashMap<String, Object> outPutIPs;
                HashMap<String, Object> outPutMPs;
                ArrayList<String> IPsLabels;
                ArrayList<String> MPsLabels;
                
                public void setDocumentLocator(Locator locator)
                {
                }
                
                public void characters(char ch[], int start, int length)
                {
                    this.content.append(ch, start, length);
                }
                
                //todos os ifs deste metodo serao ativados quando o parser encontrar <....>
                public void startElement(String uri, String localName, String qName, Attributes attributes)
                {
                    
                    if ("OutPut".equals(qName))
                    {
                        writer=new TableWriter();
                        writerBoolean = true;
                    }
                    
                    if ("OutPutNode".equals(qName))
                    {
                        string=attributes.getValue("label");
                    }
                    
                    if ("OutPutDisplacement".equals(qName))
                    {
                    }
                    
                    if ("OutPutElement".equals(qName))
                    {
                        string=attributes.getValue("label");
                        outPutIPs = new HashMap<String, Object>(2);
                        IPsLabels = new ArrayList<String>();
                    }
                    
                    if ("OutPutIP".equals(qName))
                    {
                        string1=attributes.getValue("label");
                        IPsLabels.add(string1);
                        outPutMPs = new HashMap<String, Object>(2);
                        MPsLabels = new ArrayList<String>();
                    }
                    
                    if ("OutPutMP".equals(qName))
                    {
                        string2=attributes.getValue("label");
                        MPsLabels.add(string2);
                    }
                    
                    if ("OutPutVariables".equals(qName))
                    {
                    }
                    
                    
                } // END OF STAR ELEMENT*********************************************
                    
                                    
                //    todos os ifs deste metodo serao ativados quando o parser encontrar </....>
                public void endElement(String uri, String localName, String qName)
                {
                    
                    if ("OutPut".equals(qName))
                    {
                    }
                    
                    if ("OutPutNode".equals(qName))
                    {
                        writer.addNodeLabel(string);
                        writer.setOutPutNodes(string,nodesVars);
                    }
                    
                    if ("OutPutDisplacement".equals(qName))
                    {
                        aux = new ArrayList<Integer>();
                        //StringTokenizer e apenas um quebrador de strings
                        StringTokenizer stk = new StringTokenizer(content.toString()," ");
                        while (stk.hasMoreTokens()) {
                            String aux1 = stk.nextToken().toString();
                            if (aux1.equals("dx")) {
                                Integer dx = new Integer(0);    
                                aux.add(dx);
                            }
                            if (aux1.equals("dy")) {
                                Integer dy = new Integer(1);
                                aux.add(dy);
                            }
                            if (aux1.equals("dz")) {
                                Integer dz = new Integer(2);
                                aux.add(dz);
                            }
                            if (aux1.equals("rx")) {
                                Integer rx = new Integer(3);
                                aux.add(rx);
                            }
                            if (aux1.equals("ry")) {
                                Integer ry = new Integer(4);
                                aux.add(ry);
                            }
                            if (aux1.equals("rz")) {
                                Integer rz = new Integer(5);
                                aux.add(rz);
                            }
                        }
                        
                        nodesVars = new int[aux.toArray().length];
                        for (int i = 0; i < aux.toArray().length; i++) {
                            nodesVars[i]=((Integer)aux.get(i)).intValue();
                        }
                    }
                    
                    if ("OutPutElement".equals(qName))
                    {
                        writer.addElementLabel(string);
                        writer.setOutPutElements(string,outPutIPs);
                        writer.setOutPutElements("LABELS",IPsLabels);
                    }
                    
                    if ("OutPutIP".equals(qName))
                    {
                        outPutIPs.put(string1,outPutMPs);
                        outPutIPs.put("LABELS",MPsLabels);
                    }
                    
                    if ("OutPutMP".equals(qName))
                    {
                        outPutMPs.put(string2,MPVars);
                    }
                    
                    if ("OutPutVariables".equals(qName))
                    {
                        aux = new ArrayList<Integer>();
                        //StringTokenizer e apenas um quebrador de strings
                        StringTokenizer stk = new StringTokenizer(content.toString()," ");
                        while (stk.hasMoreTokens()) {
                            String aux1 = stk.nextToken().toString();
                            if (aux1.equals("Exx")) {
                                Integer exx = new Integer(0);
                                aux.add(exx);
                            }
                            if (aux1.equals("Exy")) {
                                Integer exy = new Integer(1);
                                aux.add(exy);
                            }
                            if (aux1.equals("Exz")) {
                                Integer exz = new Integer(2);
                                aux.add(exz);
                            }
                            if (aux1.equals("Sxx")) {
                                Integer sxx = new Integer(6);
                                aux.add(sxx);
                            }
                            if (aux1.equals("Sxy")) {
                                Integer sxy = new Integer(7);
                                aux.add(sxy);
                            }
                            if (aux1.equals("Sxz")) {
                                Integer sxz = new Integer(8);
                                aux.add(sxz);
                            }
                        }
                        
                        MPVars = new int[aux.toArray().length];
                        for (int i = 0; i < aux.toArray().length; i++) {
                            MPVars[i]=((Integer)aux.get(i)).intValue();
                        }
                    }
                    
                    
                    content = new StringBuffer();
                    
                }//END OF ENDELEMENT*********************************************
                
            });//END OF PARSE*******************************************************
            
        }//END OF TRY*******************************************************************
            
        catch (ParserConfigurationException pce) 
        {
            System.out.println("Could not create that parser.");
            System.out.println(pce.getMessage());
            
            System.exit(1);
        }
        catch (SAXException se)
        {
            System.out.println("Problem with the SAX parser.");
            System.out.println(se.getMessage());
            System.exit(2);
        }
        catch (IOException ioe)
        {
            System.out.println("Error reading file.");
            System.out.println(ioe.getMessage());
            System.exit(3);
        }
        
        if(writerBoolean==false) {
         return;   
        }
        
        File newdir0 = new File("RESULTS");
        if (newdir0.mkdir());
        File newdir1 = new File(newdir0.getAbsolutePath()+File.separator+this.getSolution().getLabel());
        if (newdir1.mkdir());
        File newdir2 = new File(newdir1.getAbsolutePath()+File.separator+"TABLEs");
        if (newdir2.mkdir());
        
        this.nodeTable = new File(newdir2.getAbsolutePath()+File.separator+this.getSolution().getLabel()+"-NODEs_EQUILIBRIUMPATH"+".xls");
        s = new String[writer.getNumberOfOutPutNodes()];
        for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
            s[i]= "NODE#"+writer.getOutPutNodeLabel(i)+"\n\n"+"STEP";
            for (int j = 0; j<writer.getOutPutNodesIntArray(writer.getOutPutNodeLabel(i)).length; j++) {
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==0) {
                    s[i]+="\t" + "TRANSL_X";
                }
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==1) {
                    s[i]+="\t" + "TRANSL_Y";
                }
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==2) {
                    s[i]+="\t" + "TRANSL_Z";
                }
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==3) {
                    s[i]+="\t" + "ROTAT_X ";
                }
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==4) {
                    s[i]+="\t" + "ROTAT_Y ";
                }
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==5) {
                    s[i]+="\t" + "ROTAT_Z ";
                }
            }
            s[i]+="\t"+"LOADFACTOR";
        }
        
        File newdir3 = new File("RESULTS");
        if (newdir3.mkdir());
        File newdir4 = new File(newdir3.getAbsolutePath()+File.separator+this.getSolution().getLabel());
        if (newdir4.mkdir());
        File newdir5 = new File(newdir4.getAbsolutePath()+File.separator+"TABLEs");
        if (newdir5.mkdir());
        
        this.elementTable = new File(newdir5.getAbsolutePath()+File.separator+this.getSolution().getLabel()+"-MPs_EQUILIBRIUMPATH"+".xls");
        s1 = new String[this.writer.getOutPutElementTotalNumberOfMPs()];
        String elem;
        String ip;
        String mp;
        int x=0;
            for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
                for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                    for (int k = 0; k < this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(m)); k++) {
                        elem = this.writer.getOutPutElementLabel(m);
                        ip = this.writer.getOutPutElementIPLabel(j);
                        mp = this.writer.getOutPutElementIPMPLabel(elem, k);
                        s1[x]= "ELEMENT#"+elem+"  "+ip+"  "+mp+"\n\n"+"STEP"+"\t"+"LOADFACTOR";
                        for (int n=0; n<this.writer.getOutPutElementIPMPVariablesIntArray(elem, ip, mp).length; n++) {
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==0) {
                                s1[x]+="\t" + "EPSILON_XX";
                            }
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==1) {
                                s1[x]+="\t" + "EPSILON_XY";
                            }
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==2) {
                                s1[x]+="\t" + "EPSILON_XZ";
                            }
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==6) {
                                s1[x]+="\t" + "SIGMA_XX";
                            }
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==7) {
                                s1[x]+="\t" + "SIGMA_XY";
                            }
                            if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==8) {
                                s1[x]+="\t" + "SIGMA_XZ";
                            }
                        }
                        x++;
                    }
                }
            }
            
    }//END OF FILLMODELFROMFILE**********************************************************

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.persistence.Persistence#fillFileFromModel()
     */
    public void fillFileFromModel() {
        
        if(writerBoolean==true) {
            
        //Creating formator
        DecimalFormat fmt = new DecimalFormat();
        DecimalFormatSymbols fsym = new DecimalFormatSymbols();
        fsym.setDecimalSeparator('.');
        fmt.setDecimalFormatSymbols(fsym);
        fmt.applyPattern("0.000E00");
        DecimalFormat fmt2 = new DecimalFormat();
        fmt2.applyPattern("000");
        DecimalFormat fmt3 = new DecimalFormat();
        fmt3.setDecimalFormatSymbols(fsym);
        fmt3.applyPattern("0.00");
        
        for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
            s[i]+="\n";
            s[i]+=(String.valueOf(fmt2.format(((EquilibriumPath)solution).getStep().getLabel())));
            s[i]+=("    ");
            
            for (int j = 0; j<writer.getOutPutNodesIntArray((writer.getOutPutNodeLabel(i))).length; j++) {
                if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==0) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(0))));
                }
                else if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==1) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(1))));
                }
                else if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==2) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(2))));
                }
                else if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==3) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(3))));
                }
                else if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==4) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(4))));
                }
                else if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==5) {
                    s[i]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(5))));
                }
                else {
                    s[i]+=("\n");
                }
            }
            s[i]+="\t"+(String.valueOf(fmt.format(((EquilibriumPath)solution).getStep().getLoadFactorTotal())));
        }
        
        String elem;
        String ip;
        String mp;
        int x=0;
        for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
            for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                for (int k = 0; k < this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(m)); k++) {
                    elem = this.writer.getOutPutElementLabel(m);
                    ip = this.writer.getOutPutElementIPLabel(j);
                    mp = this.writer.getOutPutElementIPMPLabel(elem, k);
                    s1[x]+="\n";
                    if (model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).constitutiveContainsKey("STRAINS")) {
                    s1[x]+=(String.valueOf(fmt2.format(((EquilibriumPath)solution).getStep().getLabel())));
                    s1[x]+=("\t"+"    ");
                    s1[x]+=(String.valueOf(fmt.format(((EquilibriumPath)solution).getStep().getLoadFactorTotal())));
                    for (int n=0; n<this.writer.getOutPutElementIPMPVariablesIntArray(elem, ip, mp).length; n++) {
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==0) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(0))));
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==1) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(1))));
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==2) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(2))));
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==6) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(0))));
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==7) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(1))));
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==8) {
                            s1[x]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(2))));
                        }
                    }
                    x++;
                    }
                }
            }
        }
        
        if (((EquilibriumPath)solution).getStep().getLabel()==1) {
        	
        	s4 = new String[writer.getOutPutNodesIntArray(writer.getOutPutNodeLabel(0)).length];
        	
        	for (int n=0; n<s4.length; n++) {
                s4[n]="";
            }
        	
        	s5 = new String[writer.getNumberOfOutPutNodes()*writer.getOutPutNodesIntArray(writer.getOutPutNodeLabel(0)).length];
        	
        	for (int n=0; n<s5.length; n++) {
                s5[n]="";
            }
        	
        	for (int j = 0; j<writer.getOutPutNodesIntArray(writer.getOutPutNodeLabel(0)).length; j++) {
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==0) {
                        s4[j]+="\n\n" + "TRANSL_X";
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==1) {
                        s4[j]+="\n\n" + "TRANSL_Y";
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==2) {
                        s4[j]+="\n\n" + "TRANSL_Z";
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==3) {
                        s4[j]+="\n\n" + "ROTAT_X ";
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==4) {
                        s4[j]+="\n\n" + "ROTAT_Y ";
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(0),j)==5) {
                        s4[j]+="\n\n" + "ROTAT_Z ";
                    }
                    s4[j]+="\n\nNODE#\tCOORD_X\tCOORD_Y\tCOORD_Z";
        	for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
        	
        		s5[i+writer.getNumberOfOutPutNodes()*j]+= "\n"+writer.getOutPutNodeLabel(i);
        		s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getX())));
        		s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getY())));
        		s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getZ())));
            }
        	}
        	
            for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
                for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                        elem = this.writer.getOutPutElementLabel(m);
                        ip = this.writer.getOutPutElementIPLabel(j);
                        mp = this.writer.getOutPutElementIPMPLabel(elem, 0);
                        s2 = new String[this.writer.getOutPutElementIPMPVariablesIntArray(elem, ip, mp).length];
                }
            }
            
            for (int n=0; n<s2.length; n++) {
                s2[n]="";
            }

            int x1=0;
            
            for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
                for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                    
                    elem = this.writer.getOutPutElementLabel(m);
                    ip = this.writer.getOutPutElementIPLabel(j);
                    mp = this.writer.getOutPutElementIPMPLabel(elem, 0);                    
                    s2[x1]= "ELEMENT#"+elem+"  "+ip;
                    s2[x1]+="\n\n"+"SECTION PROPERTIES:\n";
                    s2[x1]+="Area =\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getGeometricProperties().getArea())))+"\n";
                    s2[x1]+="InertiaZ =\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getGeometricProperties().getInertiaZ())))+"\n";
                    s2[x1]+="InertiaY =\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getGeometricProperties().getInertiaY())))+"\n";
                    s2[x1]+="PolarInertia =\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getGeometricProperties().getInertiaX())))+"\n\n";
                    
                    for (int n=0; n<s2.length; n++) {
                        
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==0) {
                            s2[x1]+="EPSILON_XX";
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==1) {
                            s2[x1]+="EPSILON_XY";
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==2) {
                            s2[x1]+="EPSILON_XZ";
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==6) {
                            s2[x1]+="SIGMA_XX";
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==7) {
                            s2[x1]+="SIGMA_XY";
                        }
                        if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==8) {
                            s2[x1]+="SIGMA_XZ";
                        }
                        
                        s2[x1]+="\n\nMPOINT";
                        s2[x1]+=("\t"+"COORD_Z");
                        s2[x1]+=("\t"+"COORD_Y");
                        x1++;
                }
                }
            }
            
            s3 = new String[s2.length*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))];
            x1=0;
            for (int q=0; q<s2.length; q++) {
            for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
                for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                    for (int k = 0; k < this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(m)); k++) {
                        elem = this.writer.getOutPutElementLabel(m);
                        ip = this.writer.getOutPutElementIPLabel(j);
                        mp = this.writer.getOutPutElementIPMPLabel(elem, k);
                        s3[x1]="\n"+mp;
                        s3[x1]+="\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getPoint().getZ())));
                        s3[x1]+="\t"+(String.valueOf(fmt.format(model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getPoint().getY())));
                        x1++;
                    }
                }
            }
            }
        }
        
        for (int n=0; n<s2.length; n++) {
                s2[n]+="\t"+"STEP#"+(String.valueOf(fmt2.format(((EquilibriumPath)solution).getStep().getLabel())));
        }
        
        int x1=0;
        for (int m = 0; m < this.writer.getNumberOfOutPutElements(); m++) {
            for (int j = 0; j < this.writer.getOutPutElementNumberOfIPs(); j++) {
                for (int k = 0; k < this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(m)); k++) {
                    elem = this.writer.getOutPutElementLabel(m);
                    ip = this.writer.getOutPutElementIPLabel(j);
                    mp = this.writer.getOutPutElementIPMPLabel(elem, k);
                    if (model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).constitutiveContainsKey("STRAINS")) {
                    for (int n=0; n<this.writer.getOutPutElementIPMPVariablesIntArray(elem, ip, mp).length; n++) {
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==0) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(0))));
                    }
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==1) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(1))));
                    }
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==2) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")).getElement(2))));
                    }
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==6) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(0))));
                    }
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==7) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(1))));
                    }
                    if(this.writer.getOutPutElementIPMPVariablesInt(elem, ip, mp, n)==8) {
                        s3[x1+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))]+="\t"+(String.valueOf(fmt.format(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getDualInternalVariables(((IVector)model.getElement(elem).getDegeneration(ip).getMaterialPoint(mp).getConstitutiveVariables("STRAINS")))).getElement(2))));
                    }
            }
            x1++;
                    }
        }
        }
        }
        
        
        for (int n=0; n<s4.length; n++) {
                s4[n]+="\t"+"STEP#"+(String.valueOf(fmt2.format(((EquilibriumPath)solution).getStep().getLabel())));
            }
        
        for (int j = 0; j<writer.getOutPutNodesIntArray(writer.getOutPutNodeLabel(0)).length; j++) {
                for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==0) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(0))));
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==1) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(1))));
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==2) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(2))));
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==3) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(3))));
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==4) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(4))));
                    }
                    if(writer.getOutPutNodesInt(writer.getOutPutNodeLabel(i),j)==5) {
                        s5[i+writer.getNumberOfOutPutNodes()*j]+="\t"+(String.valueOf(fmt.format(model.getNode(writer.getOutPutNodeLabel(i)).getNodeValues(Node.STATE_VARIABLE).getDoublePointValue(5))));
                    }
                }
    }
        
        
        
        
        if (((EquilibriumPath)solution).getStep().getLabel()==((EquilibriumPath)solution).getNumMaxSteps()) {
            for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
                this.results+=s[i];
                this.results+="\n\n";
            }
            
            for (int i = 0; i < this.writer.getOutPutElementTotalNumberOfMPs(); i++) {
                this.results2+=s1[i];
                this.results2+="\n\n";
            }
            
           for (int n=0; n<s2.length; n++) {
               for (int i = 0; i < this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0)); i++) {
                      s2[n]+=s3[i+n*this.writer.getOutPutElementIPNumberOfMPs(this.writer.getOutPutElementLabel(0))];
               }
           }
            
            for (int i = 0; i < s2.length; i++) {
                this.results3+=s2[i];
                this.results3+="\n\n";
            }
            
            for (int n=0; n<s4.length; n++) {
                for (int i = 0; i < writer.getNumberOfOutPutNodes(); i++) {
                       s4[n]+=s5[i+n*writer.getNumberOfOutPutNodes()];
                }
            }
            
            for (int i = 0; i < s4.length; i++) {
                this.results4+=s4[i];
                this.results4+="\n\n";
            }
            
            this.writer.writer(this.nodeTable,this.results+this.results4);
            this.writer.writer(this.elementTable,this.results2+this.results3);
        }
        }
    }

    /* (non-Javadoc)
     * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
     */
    public void update(Observable o, Object arg) {
        this.fillFileFromModel();
    }
    
}// END OF PERSISTENCE AS TABLE

